# python学习 至此开始
# 学习日期: 2023/8/28 19:00
# 学习者: 任磊


# 导入所需的库文件
import sys
import time
from socket import *
from gmssl import sm2, sm3, sm4, func
from base64 import b64encode
import SeverSign


# 自己的公私钥
my_prk = "00B9AB0B828FF68872F21A837FC303668428DEA11DCD1B24429D0C99E24EED83D5"  # 私钥
my_puk = "B9C9A6E04E9C91F7BA880429273747D7EF5DDEB0BB2FF6317EB00BEF331A83081A6994B8993F3F5D6EADDDB81872266C87C018FB4162F5AF347B483E24620207"  # 公钥

# sm3 配置
def s3_function(text):  # 定义 sm3 哈希函数
    hash_text = text.encode('UTF-8')  # 将消息进行编码
    hash_text = sm3.sm3_hash(func.bytes_to_list(hash_text))  # 将消息进行哈希
    return hash_text  # 返回哈希值  str 型


# sm4 配置
time_connect_key = "2023060820230608"  # 通信密钥
def s4_encry_function(key, text):  # sm4 加密函数
    s4 = sm4.CryptSM4()  # 实例化一个对象
    s4.set_key(key.encode(), sm4.SM4_ENCRYPT)  # 设置加密密钥
    text = str(text)  # 将明文转为字符串型
    secret_text = s4.crypt_ecb(text.encode())  # 将明文编码后，使用密钥进行加密
    return secret_text  # 返回密文  byte 型


def s4_decry_function(key, text):  # sm4 解密函数，此处得确保录入的密文为 byte 型
    s4 = sm4.CryptSM4()  # 实例化一个对象
    s4.set_key(key.encode(), sm4.SM4_DECRYPT)  # 设置解密密钥
    clear_text = s4.crypt_ecb(text)  # 对 byte 型密文解密
    return clear_text  # 返回明文  byte 型


# 配置通信环境
def get_host_ip():  # 获取本机局域网 ip 函数
    s = socket(AF_INET, SOCK_DGRAM)
    try:
        s.connect(('8.8.8.8', 80))
        ip = s.getsockname()[0]
    finally:
        s.close()
    return ip


IP = get_host_ip()  # IPV4
PORT = 9000  # 端口
Max_data = 2048  # 缓冲区大小
# 设置网络层协议，传输层协议
listenSocket = socket(AF_INET, SOCK_STREAM)  # IP协议，TCP
listenSocket.bind((IP, PORT))  # 绑定地址和端口
# 设置监听
listenSocket.listen(1)  # 设置1个监听口
print('通信环境配置完毕，等待建立连接...')
# 设置连接
dataSocket, addr = listenSocket.accept()  # 设置接收
print(f'成功连接来自{addr}的连接')
print("正在发送您的公钥:{}".format(my_puk))
# 使用系统自带的签名方法
sign_puk = SeverSign.message_sign_func(my_puk)
print("正在发送签名后您的公钥:{}".format(sign_puk))
try:
    en_connect_key = other_s2_encry_function(connect_key)  # 使用 sm2 公钥加密通信密钥
    dataSocket.send(en_connect_key.encode())  # 发送处理后的通信密钥
    print('已成功发送公钥加密后的通信密钥:{}'.format(connect_key))
    target_key = input("请输入想要发送的目标密钥:")
    en_target_key_key = s4_encry_function(connect_key, target_key)  # 使用 sm4 加密目标密钥
    dataSocket.send(en_target_key_key)  # 发送目标密钥
    print('已成功发送目标密钥')
    hash_target_key = s3_function(target_key)  # 使用 sm3 哈希计算目标密钥
    sign_data = my_s2.sign(hash_target_key.encode(), str(len(target_key)))  # 将目标密钥哈希计算后签名
    dataSocket.send(sign_data.encode())  # 将签名后的消息发送
    print("已成功发送签名消息{}".format(sign_data))
finally:
    listenSocket.close()  # 关闭监听
    dataSocket.close()  # 关闭通信
    print("通信结束")
